package com.whity.towerdefense.model;

import java.io.IOException;
import java.io.InputStream;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import com.whity.towerdefense.Utils;
import com.whity.towerdefense.view.GraphicEltFactory;

import android.util.Log;

public class UnitType
{
	// =============================================================
	// Private attributs :
	
	private static final String		TAG = "com.djm.test03.model";
	
	// General attributs
	private String 					m_Name;
	private String					m_GraphicHeartID;
	
	// Statistic
	private float					m_Life;
	private float					m_Speed;	// in Cell per second
	private float					m_Armor;
	private int						m_Bounty;
	private float					m_Damage;
	private float					m_Range;
	private float					m_Size;		// in Cell, diameter of the circle defining this unit.
	
	// =============================================================
	// Private functions
	
	private UnitType(String p_Name, String p_GraphicHeartID, float p_Life, float p_Speed, float p_Armor, int p_Bounty, float p_Damage, float p_Range, float p_Size)
	{
		m_Name				= p_Name;
		m_GraphicHeartID 	= p_GraphicHeartID;
		m_Life 				= p_Life;
		m_Speed 			= p_Speed;
		m_Armor 			= p_Armor;
		m_Bounty 			= p_Bounty;
		m_Damage			= p_Damage;
		m_Range 			= p_Range;
		m_Size				= p_Size;
	}
	
	// =============================================================
	// Public functions
	
	public UnitType(String p_Path)
	{
		m_Life 		= -1;
		m_Speed 	= -1;
		m_Armor 	= -1;
		m_Bounty 	= -1;
		m_Range 	= -1;
		
		try
		{
			// Start parsing the XML file
	        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
	        factory.setValidating(false);
	        XmlPullParser xmlParser = factory.newPullParser();
	        
	        InputStream raw = GameModel.ASSETS_MANAGER.open(Utils.UNIT_PATH + "/" + p_Path);
	        xmlParser.setInput(raw, null);
	        
	        int eventType = xmlParser.getEventType();
	        while(eventType != XmlPullParser.END_DOCUMENT)
	        {
	        	
	        	if(eventType == XmlPullParser.START_TAG)
	            {
	        		if(xmlParser.getName().equals("UnitType"))
	            	{
	        			m_Name =  xmlParser.getAttributeValue(null, "Name");
	        			m_GraphicHeartID = xmlParser.getAttributeValue(null, "Graphic");
	        			GraphicEltFactory.CreateGraphicElt(m_GraphicHeartID);
	            	}
	        		else if(xmlParser.getName().equals("Stats"))
	            	{
	        			m_Life 		= Float.parseFloat(xmlParser.getAttributeValue(null, "Life"));
	        			m_Speed 	= Float.parseFloat(xmlParser.getAttributeValue(null, "Speed"));
	        			m_Armor 	= Float.parseFloat(xmlParser.getAttributeValue(null, "Armor"));
	        			m_Bounty 	= Integer.parseInt(xmlParser.getAttributeValue(null, "Bounty"));
	        			m_Damage	= Float.parseFloat(xmlParser.getAttributeValue(null, "Damage"));
	        			m_Range 	= Float.parseFloat(xmlParser.getAttributeValue(null, "Range"));
	        			m_Size		= Float.parseFloat(xmlParser.getAttributeValue(null, "Size"));
	            	}
	            }
	        	eventType = xmlParser.next();
	        }
		}
		catch (IOException e)
	    {
	    	Log.w(TAG, e.toString());
		}
		catch (XmlPullParserException e)
		{
			Log.w(TAG, e.toString());
		}
	}
	
	public UnitType(XmlPullParser p_XmlParser) throws ParsingException, XmlPullParserException, IOException
	{
		m_Name				= "";
		m_GraphicHeartID 	= "";
		m_Life 				= -1;
		m_Speed 			= -1;
		m_Armor 			= -1;
		m_Bounty 			= -1;
		m_Range 			= -1;
		m_Size				= -1;
		
		if(!p_XmlParser.getName().equals("Unit"))
    	{
			Log.w(TAG, "Can't create a Unit type with an Xml item : " + p_XmlParser.getName());
			throw(new ParsingException("Can't create a Unit type with an Xml item : " + p_XmlParser.getName()));
		}
		
		// We get the base type of the unit
		String baseTypeId = p_XmlParser.getAttributeValue(null, "Type");
		
		if(UnitFactory.GetUnitType(baseTypeId) == null)
		{
			UnitFactory.SetUnitType(baseTypeId, new UnitType(baseTypeId));
		}
		UnitType baseType = UnitFactory.GetUnitType(baseTypeId);
		
		m_Name 				= baseType.m_Name;
		m_GraphicHeartID 	= baseType.m_GraphicHeartID;
		m_Life 				= baseType.m_Life;
		m_Speed 			= baseType.m_Speed;
		m_Armor 			= baseType.m_Armor;
		m_Bounty 			= baseType.m_Bounty;
		m_Damage			= baseType.m_Damage;
		m_Range 			= baseType.m_Range;
		m_Size				= baseType.m_Size;
		
		// We modify the new type
		Float coeff = Utils.ParseFloat(p_XmlParser, "Coeff");
		if(coeff != null)
		{
			m_Life 		*= coeff;
			m_Speed 	*= coeff;
			m_Armor 	*= coeff;
			m_Bounty 	*= coeff;
			m_Range 	*= coeff;
		}
		
		try
		{
			int eventType;
			eventType = p_XmlParser.getEventType();
			while(!(eventType == XmlPullParser.END_TAG && p_XmlParser.getName().equals("Unit")))
			{
				if(eventType == XmlPullParser.START_TAG)
	            {
					if(p_XmlParser.getName().equals("Stats"))
			    	{
						// We iterate over available attributes in the xml to set them in this UnitType
						for(int i = 0 ; i < p_XmlParser.getAttributeCount() ; i++)
						{
							String attName = p_XmlParser.getAttributeName(i);
							String attValue = p_XmlParser.getAttributeValue(i);
							
							if(attName.equals("Life"))
							{
								m_Life = Float.parseFloat(attValue);
							}
							else if(attName.equals("Speed"))
							{
								m_Speed = Float.parseFloat(attValue);
							}
							else if(attName.equals("Armor"))
							{
								m_Armor = Float.parseFloat(attValue);
							}
							else if(attName.equals("Bounty"))
							{
								m_Bounty = Integer.parseInt(attValue);
							}
							else if(attName.equals("Range"))
							{
								m_Range = Float.parseFloat(attValue);
							}
							else if(attName.equals("Size"))
							{
								m_Size = Float.parseFloat(attValue);
							}
							else
							{
								Log.w(TAG, "Unknow stat for a unit type : " + attName);
							}
						}
			    	}
	            }
				eventType = p_XmlParser.next();
			}
		}
		catch (XmlPullParserException e)
		{
			Log.w(TAG, "Can't parse Xml during UnitType initialisation. UnitType's ID : " + m_Name);
			throw(e);
		} catch (IOException e)
		{
			Log.w(TAG, "Can't parse Xml during UnitType initialisation (IO). UnitType's ID : " + m_Name);
			throw(e);
		}
	}
	
	public Unit CreateUnit(float p_X, float p_Y)
	{
		return new Unit(m_Name, m_Life, m_Speed, m_Armor, m_Bounty, m_Damage, m_Range, m_Size, GraphicEltFactory.CreateGraphicElt(m_GraphicHeartID), p_X, p_Y);
	}
	
	public UnitType Clone()
	{
		return new UnitType(m_Name, m_GraphicHeartID, m_Life, m_Speed, m_Armor, m_Bounty, m_Damage, m_Range, m_Size);
	}
	
	// =============================================================
}
